<template>
  <view>
    <uv-button
      v-if="fileList.length < max"
      :color="bgColor"
      :icon="icon ? icon : iconUplaod"
      icon-color="#fff"
      :icon-size="icon ? '40rpx' : '28rpx'"
      :text="text"
      :throttle-time="3000"
      custom-style="width: 630rpx"
      @click="checkClockInRange"
    />
    <view v-if="fileList.length > 0" class="img-list">
      <view v-for="(item, index) in fileList" :key="index" class="img-item">
        <view class="img-del" @click="deletePic(index)">
          <uv-icon name="close" color="#fff" />
        </view>
        <image
          :src="webSrc(item.url)"
          mode="aspectFill"
          @click="previewImage(item.url)"
        />
        <view class="argin" v-if="item.status == 'fail'">
          <text @click="addWatermark(index)">重新上传</text>
        </view>
        <canvas
          :canvas-id="'mark' + index"
          :style="{
            width: (item.width || 300) + 'px',
            height: (item.height || 300) + 'px',
          }"
        />
      </view>
    </view>
  </view>
</template>
<script setup>
import { ref, watch } from "vue";
import { commonUpload } from "@/request/common.js";
import { isClockInRange } from "@/request/task";
import { webSrc, timeFormat } from "@/common/mothed.js";
import iconUplaod from "@/static/login/icon_uplaod.png";
const props = defineProps({
  // 上传图片
  value: {
    type: [Array, String],
    default: [],
  },
  // 图标
  icon: {
    type: String,
    default: "",
  },
  // 按钮文字
  text: {
    type: String,
    default: "上传",
  },
  // 背景色
  bgColor: {
    type: String,
    default: "#4EA770",
  },
  // 最大上传数
  max: {
    type: [Number, String],
    default: 1,
  },
  // 时间水印
  timeMark: {
    type: Boolean,
    default: false,
  },
  // 地址水印
  addressMark: {
    type: Boolean,
    default: false,
  },
});

const fileList = ref([]); // 文件列表
const uploadFail = ref(false); // 上传失败
const emit = defineEmits(["update:value", "state"]);

watch(
  props,
  (val) => {
    fileList.value = val.value.map((i) => {
      return {
        url: i,
        status: "success",
      };
    });
  },
  { deep: true, immediate: true }
);

// 选择图片
const handleChooseImage = () => {
  uni.chooseImage({
    count: props.max - fileList.value.length, // 最大上传数
    sizeType: ["compressed"], // original 原图，compressed 压缩图
    sourceType: ["camera", "album"], // 使用相机 相册
    success: (res) => {
      uploadFail.value = true;
      emit("state", {
        noBack: uploadFail.value,
        state: "start",
      });
      fileList.value = fileList.value.concat(
        res.tempFilePaths.map((i) => {
          return { url: i, width: 300, height: 300, status: "loading" };
        })
      );
      fileList.value.forEach((item, index) => {
        addWatermark(index);
      });
    },
  });
};

// 检测是否在打卡范围内
const checkClockInRange = () => {
  uni.getLocation({
    type: "gcj02",
    success: (pos) => {
      let data = {
        resourceId: uni.getStorageSync('subPlanId'),
        latitude: pos.latitude,
        longitude: pos.longitude,
      };
      isClockInRange(data).then((res) => {
        if (res.data) {
          handleChooseImage();
        } else {
          uni.showToast({
            title: "超出作业范围",
            icon: "none",
          });
        }
      });
    },
    fail: (e) => {
      setTimeout(() => {
        checkClockInRange();
      }, 1000);
    },
  });
};

// 添加水印
const addWatermark = (index) => {
  const imageUrl = fileList.value[index].url;
  const ctx = uni.createCanvasContext("mark" + index);
  uni.getImageInfo({
    src: imageUrl,
    success: (image) => {
      fileList.value[index] = {
        url: imageUrl,
        width: image.width,
        height: image.height,
        status: "loading",
      };
      // 绘制原始图片
      ctx.drawImage(imageUrl, 0, 0, image.width, image.height);
      if (props.timeMark) {
        ctx.setFontSize(30);
        ctx.setFillStyle("rgba(255, 255, 255, 0.6)");
        ctx.setTextAlign("right");
        ctx.fillText(
          timeFormat(new Date(), "yyyy-mm-dd hh:MM:ss"),
          image.width - 20,
          image.height - 20
        );
      }

      if (props.addressMark) {
        ctx.setFontSize(30);
        ctx.setFillStyle("rgba(255, 255, 255, 0.6)");
        ctx.setTextAlign("right");
        // #ifdef APP-PLUS
        uni.getLocation({
          type: "gcj02",
          geocode: true,
          success: (res) => {
            if (res.address) {
              const { province, city, district, street, streetNum } = res.address;
              ctx.fillText(
                `${province}${city}${district}${street}${streetNum}`,
                image.width - 20,
                image.height - 70
              );
            }
          },
          fail: () => {
            ctx.fillText("定位失败", image.width - 20, image.height - 70);
          },
        });
        // #endif
        // #ifdef H5
        ctx.fillText(
          `H5不支持定位信息，仅供样式参考`,
          image.width - 20,
          image.height - 70
        );
        // #endif
      }
      ctx.draw(false, () => {
        console.log("上传前：", index);
        uni.canvasToTempFilePath({
          canvasId: "mark" + index,
          success: async (img) => {
            await uploadFilePromise(img.tempFilePath, index).then((res) => {
              console.log("上传：", fileList.value, index);
              if (res.code == 200) {
                fileList.value[index] = {
                  url: res.fileName,
                  width: image.width,
                  height: image.height,
                  status: "success",
                };
                if (fileList.value.every((i) => i.status == "success")) {
                  uploadFail.value = false;
                  emit("state", {
                    noBack: uploadFail.value,
                    state: "success",
                  });
                  emit(
                    "update:value",
                    fileList.value.map((i) => i.url)
                  );
                } else {
                  uploadFail.value = true;
                  emit("state", {
                    noBack: uploadFail.value,
                    state: "loading",
                  });
                }
              }
            });
          },
        });
      });
    },
  });
};

// 删除图片
const deletePic = (index) => {
  uni.showModal({
    title: "提示",
    content: "确定是否删除？",
    showCancel: true,
    success: ({ confirm }) => {
      if (confirm) {
        fileList.value.splice(index, 1);
        emit(
          "update:value",
          fileList.value.map((i) => i.url)
        );
        if (fileList.value.every((i) => i.status == "success")) {
          uploadFail.value = false;
          emit("state", {
            noBack: uploadFail.value,
            state: "success",
          });
        }
      }
    },
  });
};

// 预览图片
const previewImage = (url) => {
  uni.previewImage({
    urls: [webSrc(url)],
    current: webSrc(url),
  });
};

// 上传凭证图片
const uploadFilePromise = (url, index) => {
  return new Promise((resolve) => {
    commonUpload(url)
      .then((res) => {
        if (res.code == 200) {
          setTimeout(() => {
            resolve(res);
          }, 1000);
        }
      })
      .catch(() => {
        uploadFail.value = true;
        fileList.value[index].status = "fail";
        emit("state", {
          noBack: uploadFail.value,
          state: "fail",
        });
      });
  });
};
</script>
<style lang="scss" scoped>
.img-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20rpx;
  width: 630rpx;
  margin-top: 20rpx;

  .img-item {
    position: relative;
    height: 200rpx;
    overflow: hidden;
    border-radius: 8rpx;
    background: rgba(0, 0, 0, 0.1);

    .img-del {
      position: absolute;
      top: 0;
      right: 0;
      width: 42rpx;
      height: 42rpx;
      background: rgba(0, 0, 0, 0.5);
      border-radius: 0 8rpx 0 8rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1;
    }

    image {
      width: 100%;
      height: 100%;
    }
    .argin {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgb(0 0 0 / 31%);
      text-align: center;
      font-size: 14px;
      color: #f0f0f0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
}
</style>
